package com.example.encrypt.aspect;

import com.example.encrypt.annotation.Decode;
import com.example.encrypt.annotation.Encrypt;
import com.example.encrypt.utils.AESUtils;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.CodeSignature;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.annotation.Annotation;
import java.util.HashMap;
import java.util.Map;

/**
 * @description:
 * @author: wenwen
 * @date: 2020/3/3 15:34
 * @version: 1.0
 */
@Aspect
@Component
@Slf4j
public class EncryptAspect {

    @Around("execution(* com.example.encrypt.controller.*.*(..))")
    public Object systemHandleLog(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("cccccccccccccccccccccccccccccc");
        // 获取
        MethodSignature signature = (MethodSignature) pjp.getSignature();
        // 获取所有参数
        Object[] params = pjp.getArgs();

        // 获取方法上的注解
        // XXX xxx = signature.getMethod().getAnnotation(XXX.class)
        //获取所有参数上的注解
        //参数注解，1维是参数，2维是注解
        Annotation[][] annotations = signature.getMethod().getParameterAnnotations();
        for (int i = 0; i < annotations.length; i++) {
            Object param = params[i];
            Annotation[] paramAnn = annotations[i];
            //参数为空，直接下一个参数
            if(param == null || paramAnn.length == 0){
                continue;
            }
            for (Annotation annotation : paramAnn) {
                // 这里判断当前注解是否为Test.class
                if(annotation.annotationType().equals(Decode.class)){
                    //校验该参数，验证一次退出该注解
                    String decryptString = AESUtils.getDecryptString((String) param);
                    //TODO 校验参数
                    params[i] = decryptString;
                    break;
                }
            }
        }

         Object proceed = pjp.proceed();
//        Object proceed = pjp.proceed(params);
        Annotation[] annotations1 = signature.getMethod().getAnnotations();
        for (Annotation annotation : annotations1) {
            if (annotation instanceof Encrypt){
                String s = (String) proceed;
                return AESUtils.getEncryptString(s);
            }
        }


        return proceed;


    }


    /**
     * @Description: 获取HttpServletRequest
     * @Author: wenwen
     * @Date: 2019/7/25 11:18
     * @Param: []
     * @Return: javax.servlet.http.HttpServletRequest
     */
    private HttpServletRequest getHttpServletRequest() {
        RequestAttributes ra = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes sra = (ServletRequestAttributes) ra;
        HttpServletRequest request = sra.getRequest();
        return request;
    }

    /**
     * 获取参数Map集合
     *
     * @param joinPoint
     * @return
     */
    private Map<String, Object> getNameAndValue(ProceedingJoinPoint joinPoint) {
        Map<String, Object> param = new HashMap<>();

        Object[] paramValues = joinPoint.getArgs();
        String[] paramNames = ((CodeSignature) joinPoint.getSignature()).getParameterNames();

        for (int i = 0; i < paramNames.length; i++) {
            param.put(paramNames[i], paramValues[i]);
        }
        return param;
    }


}
